package com.android.scj.tc;

import android.content.Context;
import android.util.Log;


import com.util.EncodingUtil;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;

import android_serialport_api.SerialPort;

/**
 * 连接通信类
 *
 * @author liuyadong
 *
 */
public class Connection {


	// 维护日记的序号
	public static long NUM = 0;
	// 存放日记内容的Map
//    public static Map<String, List<LogEntity>> context = null;
	// 所有配置文件名称
	public static Map<String, String> map = new HashMap<String, String>();

	public static boolean isWord = false;

	public static int SType;
//
//    public static DBAdapter db = null;
//
//    public static WaitRead wr = null;

	// 终端物理串号(终端机编号)
	public static String TERMINIMEI = "";
	// 测试时间
	public static long times;
	public static int KeyType = 6;
	// 定义返回键
	public static String backKey = "17";
	// 定义确认键
	public static String enterKey = "2F";
	// 激活键
	public static String activeKey = "37";
	// 检测键
	public static String detectKey = "3B";
	// 左侧按钮
	public static String initKey = "3E";
	// 右侧按钮
	public static String personalKey = "3D";
	public static String activeKey2 = "00";



	// 接受设备传输数据流
	private static InputStream inputStream = null;
	private static OutputStream outputStream = null;
	// 接收数据数组
	private byte[] bytesToRecv;
	private List<Byte> readlist = null;
	private int readlistTcount = 0;
	private long time = 0;
	public String content = "";
	public static Connection con = null;
	public static Connection getConnection() {
		if (con==null) {
			con = new Connection();
		}
		return con;
	}

	static{
		SerialPort sp;
		try {
			sp = new SerialPort(115200, 0);
			inputStream = sp.getInputStream();
			outputStream = sp.getOutputStream();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}


	/**
	 * @param context
	 *            指令
	 * @return
	 * @throws IOException
	 * @throws InterruptedException
	 */
	public String send(String context, Context context_n) throws IOException,
			InterruptedException, Exception {
	   //  String	path = File_Z.createFile(context_n);

        Log.e("发送的数据", context);
		//Write_Message.write(File_Z.dirThreeFile.toString() ,context_n ,File_Z.GetNowDate3()+"_"+context, File_Z.time2);

		outputStream.write(EncodingUtil.hex2byte(EncodingUtil.change(context)));

		if(context.substring(5*2,7*2).equals("F200"))
			return null;
		time = System.currentTimeMillis() + 5000; //5000
		int x = 0;
		while (true) {

			if (System.currentTimeMillis() <= time) {
				x = inputStream.available(); // 预测缓存区数据长度
				if (x > 0) {
					bytesToRecv = new byte[1];
					inputStream.read(bytesToRecv);
					// 第一次
					if (readlist == null) {
						// 判断头
						if (readlist == null && (bytesToRecv[0] & 0xff) == 0x55) {
							readlist = new ArrayList<Byte>();
						}
					}
					// 第二次
					if (readlist != null && readlist.size() == 1) {
						if (!((bytesToRecv[0] & 0xff) == 0xaa)) {

							// 判断头
							readlist = null;
							readlistTcount = 0;
						}
					}// 如果头是正确的话或者接着接收未接收完的数据
					if (readlist != null) {
						for (int i = 0; i < bytesToRecv.length; i++) {
							readlist.add(bytesToRecv[i]);
						}
						// 第三次跳过，第四次第五次获取长度
						if (readlist != null && readlist.size() >= 5 && readlistTcount == 0) {
							String a = Integer.toHexString(readlist.get(3) & 0xff);
							String b = Integer.toHexString(readlist.get(4) & 0xff);
							if (b.length() < 2) {
								b = "0" + b;
							}
							readlistTcount = Integer.parseInt(a + b, 16) + 7;// 内容长度N
							// +
							// (头2
							// +
							// 随机数1
							// +
							// 长度2
							// +
							// 命令集1
							// +
							// 校验1)
						}

						// 数据接收完整以后
						if (readlistTcount != 0
								&& readlist.size() >= readlistTcount) {
							byte[] bytes = new byte[readlistTcount];
							int tempindex = 0;
							for (Byte b : readlist) {
								if (tempindex == readlistTcount)
									break;

								bytes[tempindex] = b;

								tempindex++;
							}
							readlist = null;
							readlistTcount = 0;
							content = EncodingUtil.bytesToHexString(bytes);
							// 检查数据是否完整
							content = EncodingUtil.checking(content);


							if (content != null && content.substring(12, 14).equals("BF")) {
								content = "";
								readlist = null;
								readlistTcount = 0;
								continue;
							} else {
								readlist = null;
								readlistTcount = 0;
								break;
							}

						}
					}

				}
			} else {
				if (x > 0) {
					bytesToRecv = new byte[x];
					inputStream.read(bytesToRecv);
					content = "";
					readlist = null;
					readlistTcount = 0;
				}
				throw new IOException("设备交互超时,请重试!");
			}
		}
		bytesToRecv = null;
		readlist = null;
		readlistTcount = 0;
		if (content == null) {
			throw new NoSuchElementException("报文格式不正确！");
		}
        Log.e("收到的数据", content);
        //Write_Message.write(File_Z.dirThreeFile.toString()  ,context_n ,File_Z.GetNowDate3()+"_"+content, File_Z.time2);
		return content;
	}

	/**
	 * 读取数据
	 *
	 * @return
	 * @throws IOException
	 * @throws Exception
	 */
	public String read(String context, int timeOut) throws IOException,
			Exception {
		outputStream.write(EncodingUtil.hex2byte(EncodingUtil.change(context)));
		String content = "";
		int x = 0;
		long time = System.currentTimeMillis();
		while (true) {
			x = inputStream.available(); // 预测缓存区数据长度
			if (System.currentTimeMillis() - time <= timeOut) {
				if (x > 0) {
					bytesToRecv = new byte[x];
					inputStream.read(bytesToRecv);
					content += EncodingUtil.bytesToHexString(bytesToRecv);
					if (checkFF(content)) {
						break;
					}
				}
			} else {
				return null;
			}
		}
		bytesToRecv = null;
		return content;
	}

	/**
	 * 接收设备指令 (BD指令是设备发送的)
	 *
	 * @throws IOException
	 */
	public String receive() throws IOException, Exception {
		try {
			int x = 0;
			String data = "";
			x = inputStream.available(); // 预测缓存区数据长度
			if (x > 0) {
				bytesToRecv = new byte[x];
				inputStream.read(bytesToRecv);
			}
			if (x > 0) {
				data = EncodingUtil.checking(EncodingUtil
						.bytesToHexString(bytesToRecv));
				if (!data.substring(12, 14).equals("BF")) {
					return null;
				}
				bytesToRecv = null;
				return data;
			} else {
				bytesToRecv = null;
				return null;
			}
		} catch (Exception e) {
			return null;
		}

	}


	public boolean checkFF(String str) {
		if (str != null) {
			int x = str.indexOf("FF");
			int y = str.lastIndexOf("FF");
			if ((x >= 0 && y > 4) && (x % 2 == 0 && y % 2 == 0)) {
				return true;
			}
		}
		return false;
	}
}
